#include <Daemon.h>

namespace process {

logging::Log Daemon::_log = logging::LogManager.get("process.daemon");

Daemon::Daemon() 
	: _running(false) {
}

Daemon::~Daemon() {
}


bool Daemon::start() {
	if ( !_running ) {
		_running = true;
		return daemonize();
	}
	return false;
}

bool Daemon::daemonize();
	setup();

	pid_t pid;
	struct rlimit rl;
	struct sigaction sa;

	//Clear file creation mask.
	umask(0);

	//Get max number of file descriptors
	if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
		_log.fatal() << "Can not obtain file descriptor limit" << logging::end();
		exit(1);
	}

	//Become a session leader to lose controlling TTY
	if ((pid = fork()) < 0) {
		_log.fatal() << "Can't fork first daemon process" << logging::end();
		exit(1);
	} else if (pid !=0) { 
		//kill parent
		exit(0);
	}
	setsid();

	//Ensure future open won't allocate controlling TTYs
	sa.sa_handler = SIG_IGN;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if (sigaction(SIGHUP, &sa, NULL) < 0) {
		_log.fatal() << "Can't ignore SIGHUP" << logging::end();
		exit(1);
	}
	if ((pid = fork()) < 0) {
		_log.fatal() << "Can't fork second daemon process" << logging::end();
		exit(1);
	} else if (pid != 0) {
		//kill parent
		exit(0);
	}

	//change current directory
	if (chdir("/") < 0) {
		_log.fatal() << "Can't change to directory /" << logging::end();
		exit(1);
	}

	//Close all open file descriptors
	if (rl.rlim_max == RLIM_INFINITY) {
		rl.rlim_max = 1024;
	}
	for (int i=0; i < rl.rlim_max; i++) {
		close(i);
	}

	//Attach file descriptions STDIN(0), STDOUT(1), STRERR(2) to /dev/null
	fd0 = open("/dev/null", O_RDWR);
	fd1 = dup(0);
	fd2 = dup(0);

	int i, fd0, fd1, fd2;
	//Daemon setup
	//fork()
	//close open file handlers
	//fork() again
	return run();
};

}

#endif DAEMON_H

